#############################################################################
#  Copyright (C) 2007 Boscovich, Maximiliano - mboscovich@gmail.com          #
#                                                                            #
#  This program is free software; you can redistribute it and/or modify      #
#  it under the terms of the GNU General Public License as published by      #
#  the Free Software Foundation; either version 3 of the License, or         #
#  (at your option) any later version. See tht GPL_Licence.txt for details.  #
#                                                                            #
#  This program is distributed in the hope that it will be useful,           #
#  but WITHOUT ANY WARRANTY; without even the implied warranty of            #
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the              #
#  GNU General Public License for more details.                              #
#                                                                            #
##############################################################################

from sqlobject import *

from formencode import validators

class Group(SQLObject):
    class sqlmeta:
        table = "group_table"
    Name = StringCol(length=30, unique="true",
                        validator=validators.String(not_empty=True,strip=True) )
    Description = StringCol()
    Hosts = RelatedJoin( 'Host' )
    Templates = RelatedJoin( 'Template' )


class Distribution(SQLObject):
    Name = StringCol(length=10, unique="true",
                        validator=validators.String(not_empty=True, strip=True))
    Hosts = MultipleJoin('Host')


class Architecture(SQLObject):
    Type = StringCol(length=10, unique="true",
                        validator=validators.String(not_empty=True, strip=True))
    Hosts = MultipleJoin('Host')


class Office(SQLObject):
    Name = StringCol(length=50, unique="true",
                        validator=validators.String(not_empty=True, strip=True))
    Location = StringCol(length=60)
    Description = StringCol()
    Contact = StringCol()
    Phone = StringCol(length=20)
    Hosts = MultipleJoin('Host')


class Template(SQLObject):
    Category = StringCol(unique="true",
                         validator=validators.String(not_empty=True, strip=True))
    Description = StringCol()
    Hosts = MultipleJoin('Host')
    PackagesMustHave = SQLRelatedJoin('Package',
                                intermediateTable='template_package_must_have',
                                createRelatedTable=False)
    PackagesMayNotHave = SQLRelatedJoin('Package',
                            intermediateTable='template_package_may_not_have',
                            createRelatedTable=False)
    PackagesMayHave = SQLRelatedJoin('Package',
                                intermediateTable='template_package_may_have',
                                createRelatedTable=False)
    def PackagesMustHave(self):#FIXME: hay algun tema con la libreria, por lo que el self.PackagesMustHave no funciona. Por eso cree estos metodos, hasta que se solucione eso.
        list = []
        for pack in TemplatePackageMustHave.selectBy(template=self.id):
            list.append(pack.packageID)
        return list

    def PackagesMayHave(self):
        list = []
        for pack in TemplatePackageMayHave.selectBy(template=self.id):
            list.append(pack.packageID)
        return list
    
    def PackagesMayNotHave(self):
        list = []
        for pack in TemplatePackageMayNotHave.selectBy(template=self.id):
            list.append(pack.packageID)
        return list

    def addPackageMustHave(self,pack):
        new_package=TemplatePackageMustHave(template=self,package=pack)
    
    def addPackageMayHave(self,pack):
        new_package=TemplatePackageMayHave(template=self,package=pack)
    
    def addPackageMayNotHave(self,pack):
        new_package=TemplatePackageMayNotHave(template=self,package=pack)

    def delPackageMustHave(self,pack):
        package_to_del=TemplatePackageMustHave.selectBy(template=self,
                                                        package=pack)
        package_to_del[0].destroySelf()

    def delPackageMayHave(self,pack):
        package_to_del=TemplatePackageMayHave.selectBy(template=self,
                                                        package=pack)
        package_to_del[0].destroySelf()
    
    def delPackageMayNotHave(self,pack):
        package_to_del=TemplatePackageMayNotHave.selectBy(template=self,
                                                            package=pack)
        package_to_del[0].destroySelf()
    
    def setPackagesMustHave(self,list):
        currents = self.PackagesMustHave()
        for package in currents:
            if package not in list:
                self.delPackageMustHave(package)
        for package in list:
            if package not in currents:
                self.addPackageMustHave(package)

    def setPackagesMayHave(self,list):
        currents = self.PackagesMayHave()
        for package in currents:
            if package not in list:
                self.delPackageMayHave(package)
        for package in list:
            if package not in currents:
                self.addPackageMayHave(package)

    def setPackagesMayNotHave(self,list):
        currents = self.PackagesMayNotHave()
        for package in currents:
            if package not in list:
                self.delPackageMayNotHave(package)
        for package in list:
            if package not in currents:
                self.addPackageMayNotHave(package)

class TemplatePackageMustHave(SQLObject):
    class sqlmeta:
        table = "template_package_must_have"
    template = ForeignKey('Template', notNull=True, cascade=True)
    package = ForeignKey('Package', notNull=True, cascade=True)
    unique = index.DatabaseIndex(template, package, unique=True)

class TemplatePackageMayHave(SQLObject):
    class sqlmeta:
        table = "template_package_may_have"
    template = ForeignKey('Template', notNull=True, cascade=True)
    package = ForeignKey('Package', notNull=True, cascade=True)
    unique = index.DatabaseIndex(template, package, unique=True)


class TemplatePackageMayNotHave(SQLObject):
    class sqlmeta:
        table = "template_package_may_not_have"
    template = ForeignKey('Template', notNull=True, cascade=True)
    package = ForeignKey('Package', notNull=True, cascade=True)
    unique = index.DatabaseIndex(template, package, unique=True)


class HostPackageMustHave(SQLObject):
    class sqlmeta:
        table = "host_package_must_have"
    host = ForeignKey('Host', notNull=True, cascade=True)
    package = ForeignKey('Package', notNull=True, cascade=True)
    unique = index.DatabaseIndex(host, package, unique=True)


class HostPackageMayHave(SQLObject):
    class sqlmeta:
        table = "host_package_may_have"
    host = ForeignKey('Host', notNull=True, cascade=True)
    package = ForeignKey('Package', notNull=True, cascade=True)
    unique = index.DatabaseIndex(host, package, unique=True)


class HostPackageMayNotHave(SQLObject):
    class sqlmeta:
        table = "host_package_may_not_have"
    host = ForeignKey('Host', notNull=True, cascade=True)
    package = ForeignKey('Package', notNull=True, cascade=True)
    unique = index.DatabaseIndex(host, package, unique=True)


class Package(SQLObject):
    Name = StringCol(unique="true")
    HostsMustHave = SQLRelatedJoin('Host',
                                    intermediateTable='host_package_must_have',
                                    createRelatedTable=False)
    HostsMayNotHave = SQLRelatedJoin('Host',
                                intermediateTable='host_package_may_not_have',
                                createRelatedTable=False)
    HostsMayHave = SQLRelatedJoin('Host',
                                    intermediateTable='host_package_may_have',
                                    createRelatedTable=False)
    TemplatesMustHave = SQLRelatedJoin('Template',
                                intermediateTable='template_package_must_have',
                                createRelatedTable=False)
    TemplatesMayNotHave = SQLRelatedJoin('Template',
                            intermediateTable='template_package_may_not_have',
                            createRelatedTable=False)
    TemplatesMayHave = SQLRelatedJoin('Template',
                                intermediateTable='template_package_may_have',
                                createRelatedTable=False)

class Host(SQLObject):
    MacAddress = StringCol(length=17, unique="true",
                        validator=validators.String(not_empty=True, strip=True))
    DnsName = StringCol(length=16,unique="true", 
                        validator=validators.String(not_empty=True, strip=True))
    Office = ForeignKey('Office', cascade='null')   
    Architecture = ForeignKey('Architecture', cascade='null')
    Distribution = ForeignKey('Distribution', cascade='null')
    Template = ForeignKey('Template', cascade='null')
    Groups = RelatedJoin('Group')
    PackagesMustHave = SQLRelatedJoin('Package',
                                    intermediateTable='host_package_may_have',
                                    createRelatedTable=False)
    PackagesMayNotHave = SQLRelatedJoin('Package',
                                    intermediateTable='host_package_may_have',
                                    createRelatedTable=False)
    PackagesMayHave = SQLRelatedJoin('Package',
                                    intermediateTable='host_package_may_have',
                                    createRelatedTable=False)
    def PackagesMustHave(self):#FIXME: hay algun tema con la libreria, por lo que el self.PackagesMustHave no funciona. Por eso cree estos metodos, hasta que se solucione eso.
        list = []
        for pack in HostPackageMustHave.selectBy(host=self.id):
            list.append(pack.packageID)
        return list

    def PackagesMayHave(self):
        list = []
        for pack in HostPackageMayHave.selectBy(host=self.id):
            list.append(pack.packageID)
        return list
    
    def PackagesMayNotHave(self):
        list = []
        for pack in HostPackageMayNotHave.selectBy(host=self.id):
            list.append(pack.packageID)
        return list
    
    def setPackages(self, must_have, may_not_have, may_have):
        #FIXME: separar en tres metodos, uno para uno
        currentMustHave = self.PackagesMustHave()
        currentMayHave = self.PackagesMayHave()
        currentMayNotHave = self.PackagesMayNotHave()
        for package in currentMustHave:
            if package not in must_have:
                self.delPackageMustHave(package)

        for package in currentMayHave:
            if package not in may_have:
                self.delPackageMayHave(package)

        for package in currentMayNotHave:
            if package not in may_not_have:
                self.delPackageMayNotHave(package)

        for package in must_have:
            if package not in currentMustHave:
                self.addPackageMustHave(package)
        
        for package in may_not_have:
            if package not in currentMayNotHave:
                self.addPackageMayNotHave(package)
        
        for package in may_have:
            if package not in currentMayHave:
                self.addPackageMayHave(package)

    
    def addPackageMustHave(self,pack):
        new_package=HostPackageMustHave(host=self,package=pack)
    
    def addPackageMayHave(self,pack):
        new_package=HostPackageMayHave(host=self,package=pack)
    
    def addPackageMayNotHave(self,pack):
        new_package=HostPackageMayNotHave(host=self,package=pack)
    
    def delPackageMustHave(self,pack):
        packageToDel=HostPackageMustHave.selectBy(host=self,package=pack)
        packageToDel[0].destroySelf()

    def delPackageMayNotHave(self,pack):
        packageToDel=HostPackageMayNotHave.selectBy(host=self,package=pack)
        packageToDel[0].destroySelf()
    
    def delPackageMayHave(self,pack):
        packageToDel=HostPackageMayHave.selectBy(host=self,package=pack)
        packageToDel[0].destroySelf()
    
